#include <CpLog.h>
#include "CpPolynom1D.h"
#include <TMath.h>
#include <TF1.h>

ClassImp(CpPolynom1D);

//______________________________________________________________________________
CpPolynom1D::CpPolynom1D(): TObject()
{
//
// Constructor
//

   CpDebug(CpLog::kDebug + 5, "<-");
   CpDebug(CpLog::kDebug + 5, "->");

}

//______________________________________________________________________________
CpPolynom1D::~CpPolynom1D()
{
//
// Destructor.
//
   CpDebug(CpLog::kDebug + 5, "<-");
   CpDebug(CpLog::kDebug + 5, "->");
}


//________________________________________________________________________________________________________________
Int_t CpPolynom1D::GetNumberOfParameters(Int_t grade)
{
//
// Gets Number of parameters
//
//   CpDebug(CpLog::kDebug+5,"<-");
   switch (grade) {
      case 0:
         return 1;
      case 1:
         return 2;
      case 2:
         return 3;
      case 3:
         return 4;
      case 4:
         return 5;
      case 5:
         return 6;
      case 6:
         return 7;
      case 7:
         return 8;
      case 8:
         return 9;
      case 9:
         return 10;
      case 10:
         return 11;
      case 11:
         return 12;
      default :
         return -1;

   }

//   CpDebug(CpLog::kDebug+5,"->");


}



Double_t CpPolynom1D::Degree0(Double_t *x, Double_t *par)
{
   // x^0
   Double_t r = par[0] + x[0] * 0;
   return r;
}


Double_t CpPolynom1D::Degree1(Double_t *x, Double_t *par)
{
   Double_t r = Degree0(x, par);

   // x
   r += par[1] * TMath::Power(x[0], 1);
   return r;
}


Double_t CpPolynom1D::Degree2(Double_t *x, Double_t *par)
{
   Double_t r = Degree1(x, par);

   // x^2
   r += par[2] * TMath::Power(x[0], 2);
   return r;
}


Double_t CpPolynom1D::Degree3(Double_t *x, Double_t *par)
{
   Double_t r = Degree2(x, par);

   // x^3
   r += par[3] * TMath::Power(x[0], 3);
   return r;
}
Double_t CpPolynom1D::Degree4(Double_t *x, Double_t *par)
{
   Double_t r = Degree3(x, par);

   // x^4
   r += par[4] * TMath::Power(x[0], 4);
   return r;
}
Double_t CpPolynom1D::Degree5(Double_t *x, Double_t *par)
{
   Double_t r = Degree4(x, par);

   // x^5
   r += par[5] * TMath::Power(x[0], 5);
   return r;
}
Double_t CpPolynom1D::Degree6(Double_t *x, Double_t *par)
{
   Double_t r = Degree5(x, par);

   // x^6
   r += par[6] * TMath::Power(x[0], 6);
   return r;
}
Double_t CpPolynom1D::Degree7(Double_t *x, Double_t *par)
{
   Double_t r = Degree6(x, par);

   // x^7
   r += par[7] * TMath::Power(x[0], 7);
   return r;
}
Double_t CpPolynom1D::Degree8(Double_t *x, Double_t *par)
{
   Double_t r = Degree7(x, par);

   // x^8
   r += par[8] * TMath::Power(x[0], 8);
   return r;
}
Double_t CpPolynom1D::Degree9(Double_t *x, Double_t *par)
{
   Double_t r = Degree8(x, par);

   // x^9
   r += par[9] * TMath::Power(x[0], 9);
   return r;
}
Double_t CpPolynom1D::Degree10(Double_t *x, Double_t *par)
{
   Double_t r = Degree9(x, par);

   // x^10
   r += par[10] * TMath::Power(x[0], 10);
   return r;
}

Double_t CpPolynom1D::DerivateXDegree0(Double_t */*x*/, Double_t */*par*/)
{
   // x^0
//    Double_t r = par[0] * 0 + x[0] * 0;
   return 0;
}


Double_t CpPolynom1D::DerivateXDegree1(Double_t *x, Double_t *par)
{
   Double_t r = DerivateXDegree0(x, par);

   // x
   r += par[1];
   return r;
}


Double_t CpPolynom1D::DerivateXDegree2(Double_t *x, Double_t *par)
{
   Double_t r = DerivateXDegree1(x, par);

   // x^2
   r += 2 * par[2] * TMath::Power(x[0], 1);
   return r;
}


Double_t CpPolynom1D::DerivateXDegree3(Double_t *x, Double_t *par)
{
   Double_t r = DerivateXDegree2(x, par);

   // x^3
   r += 3 * par[3] * TMath::Power(x[0], 2);
   return r;
}
Double_t CpPolynom1D::DerivateXDegree4(Double_t *x, Double_t *par)
{
   Double_t r = DerivateXDegree3(x, par);

   // x^4
   r += 4 * par[4] * TMath::Power(x[0], 3);
   return r;
}
Double_t CpPolynom1D::DerivateXDegree5(Double_t *x, Double_t *par)
{
   Double_t r = DerivateXDegree4(x, par);

   // x^5
   r += 5 * par[5] * TMath::Power(x[0], 4);
   return r;
}
Double_t CpPolynom1D::DerivateXDegree6(Double_t *x, Double_t *par)
{
   Double_t r = DerivateXDegree5(x, par);

   // x^6
   r += 6 * par[6] * TMath::Power(x[0], 5);
   return r;
}
Double_t CpPolynom1D::DerivateXDegree7(Double_t *x, Double_t *par)
{
   Double_t r = DerivateXDegree6(x, par);

   // x^7
   r += 7 * par[7] * TMath::Power(x[0], 6);
   return r;
}
Double_t CpPolynom1D::DerivateXDegree8(Double_t *x, Double_t *par)
{
   Double_t r = DerivateXDegree7(x, par);

   // x^8
   r += 8 * par[8] * TMath::Power(x[0], 7);
   return r;
}
Double_t CpPolynom1D::DerivateXDegree9(Double_t *x, Double_t *par)
{
   Double_t r = DerivateXDegree8(x, par);

   // x^9
   r += 9 * par[9] * TMath::Power(x[0], 8);
   return r;
}
Double_t CpPolynom1D::DerivateXDegree10(Double_t *x, Double_t *par)
{
   Double_t r = DerivateXDegree9(x, par);

   // x^10
   r += 10 * par[10] * TMath::Power(x[0], 9);
   return r;
}

Double_t CpPolynom1D::Derivate2XDegree0(Double_t */*x*/, Double_t */*par*/)
{
   // x^0
//    Double_t r = par[0] * 0 + x[0] * 0;
   return 0;
}


Double_t CpPolynom1D::Derivate2XDegree1(Double_t */*x*/, Double_t *)
{
   //Double_t r = Derivate2XDegree0(x, par);

   // x
  // r += par[1];
   return 0;
}


Double_t CpPolynom1D::Derivate2XDegree2(Double_t *x, Double_t *par)
{
   Double_t r = Derivate2XDegree1(x, par);

   // x^2
   r += 2 * par[2];
   return r;
}


Double_t CpPolynom1D::Derivate2XDegree3(Double_t *x, Double_t *par)
{
   Double_t r = Derivate2XDegree2(x, par);

   // x^3
   r += 6 * par[3] * TMath::Power(x[0], 1);
   return r;
}
Double_t CpPolynom1D::Derivate2XDegree4(Double_t *x, Double_t *par)
{
   Double_t r = Derivate2XDegree3(x, par);

   // x^4
   r += 12 * par[4] * TMath::Power(x[0], 2);
   return r;
}
Double_t CpPolynom1D::Derivate2XDegree5(Double_t *x, Double_t *par)
{
   Double_t r = Derivate2XDegree4(x, par);

   // x^5
   r += 20 * par[5] * TMath::Power(x[0], 3);
   return r;
}
Double_t CpPolynom1D::Derivate2XDegree6(Double_t *x, Double_t *par)
{
   Double_t r = Derivate2XDegree5(x, par);

   // x^6
   r += 30 * par[6] * TMath::Power(x[0], 4);
   return r;
}
Double_t CpPolynom1D::Derivate2XDegree7(Double_t *x, Double_t *par)
{
   Double_t r = Derivate2XDegree6(x, par);

   // x^7
   r += 42 * par[7] * TMath::Power(x[0], 5);
   return r;
}
Double_t CpPolynom1D::Derivate2XDegree8(Double_t *x, Double_t *par)
{
   Double_t r = Derivate2XDegree7(x, par);

   // x^8
   r += 56 * par[8] * TMath::Power(x[0], 6);
   return r;
}
Double_t CpPolynom1D::Derivate2XDegree9(Double_t *x, Double_t *par)
{
   Double_t r = Derivate2XDegree8(x, par);

   // x^9
   r += 72 * par[9] * TMath::Power(x[0], 7);
   return r;
}
Double_t CpPolynom1D::Derivate2XDegree10(Double_t *x, Double_t *par)
{
   Double_t r = Derivate2XDegree9(x, par);

   // x^10
   r += 90 * par[10] * TMath::Power(x[0], 8);
   return r;
}

